/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023-2024.
 * Description: RTOS self-developed code for dev.c
 * Author: Wang Haitao
 * Create: 2023/9/14
 */

#ifdef CONFIG_RTOS_NET_SKB_FAST_XMIT
int dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
		struct net_device *dev, struct netdev_queue *txq)
{
	return __dev_xmit_skb(skb, q, dev, txq);
}
EXPORT_SYMBOL(dev_xmit_skb);
#endif

#ifdef CONFIG_RTOS_ONT_MIRROR_FWD
void mirror_fwd_by_ptype(struct sk_buff *skb)
{
	struct packet_type *pt_cur = NULL;
	struct net_device *dev_bak = NULL;

	if (unlikely(!skb))
		return;

	dev_bak = skb->dev;

	list_for_each_entry_rcu(pt_cur, &ptype_all, list) {
		if (pt_cur)
			(void)deliver_skb(skb, pt_cur, dev_bak);
	}

	list_for_each_entry_rcu(pt_cur, &skb->dev->ptype_all, list) {
		if (pt_cur)
			(void)deliver_skb(skb, pt_cur, dev_bak);
	}
}
EXPORT_SYMBOL_NS(mirror_fwd_by_ptype, HW_RTOS_NS);
#endif

#ifdef CONFIG_RTOS_NET_PV_FW
static bool trace_vendor_netif_receive_skb(struct sk_buff *skb, int *ret)
{
	struct net_device *dev = skb->dev;

	if (g_pv_fw_ing) {
		*ret = (*g_pv_fw_ing)(skb);
		if (*ret == NET_RX_DROP) {
			atomic_long_inc(&dev->tx_dropped);
			kfree_skb_list(skb);
			return true;
		} else if (*ret == NET_RX_SUCCESS) {
			return true;
		}
	}
	return false;
}

static void trace_vendor_netif_receive_skb_list(struct list_head *head)
{
	struct net_device *dev;
	struct sk_buff *skb, *next;
	int ret;
	struct list_head sub_list;
	INIT_LIST_HEAD(&sub_list);
	list_for_each_entry_safe(skb, next, head, list) {
		dev = skb->dev;
		if (g_pv_fw_ing) {
			skb_list_del_init(skb);
			ret = (*g_pv_fw_ing)(skb);
			if (ret == NET_RX_DROP) {
				atomic_long_inc(&dev->tx_dropped);
				kfree_skb_list(skb);
				continue;
			} else if (ret == NET_RX_SUCCESS) {
				continue;
			} else {
				list_add_tail(&skb->list, &sub_list);
			}
		}
	}
	list_splice_init(&sub_list, head);
}
#else
static inline bool trace_vendor_netif_receive_skb(struct sk_buff *skb, int *ret)
{
	return false;
}
static inline void trace_vendor_netif_receive_skb_list(struct list_head *head)
{
}
#endif
